package com.lazy.localfs;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * 本地文件系统管理, 负责文件的读取, 删除等
 * 目录设计位gps000000 - gps999999 有 1000 000 个文件夹
 * 每个文件夹存放 10G的文件( 1M * 10 000)个
 * 
 * 根据实际需求 保存多少个目录文件
 * 
 * @author luodan
 *
 */
public final class LocalFsMgr {
    private static final Logger logger = LoggerFactory.getLogger(LocalFsMgr.class);
    
    private static AtomicInteger dirIndex = new AtomicInteger(0);
    
    private static final String  DIR_PREFIX = "gps";
    private static final String  DIR_ROOTDIR = "data/";
    private static final int DIR_FILE_LIMIT = 1000;//10000; // 10K
    private static final int DIR_LIMIT = 10; // 
    
    private static LocalFsMgr localFsMgr;
    
    private List<String>  sortedFileList;
    Lock lock = new ReentrantLock();// 锁  
    
    private LocalFsMgr(){
        init();
    }
    
    /** 获取唯一实例 */
    public static LocalFsMgr getInstance() {
        if(localFsMgr == null) {
            localFsMgr = new LocalFsMgr();
        }
        return localFsMgr;
    }
    
    private void init() {
        sortedFileList = getDataDir();
        dirIndex.set(getLastFileIndex(sortedFileList));
    }
 
    /**
     * 获取所有的子目录, 并返回排序好的文件目录
     * @return
     */
    public List<String> getDataDir() {
        File pDir = new File(DIR_ROOTDIR);
        File[] files = pDir.listFiles();
        List<String> fileList = new ArrayList<String>();
        for (File file:files) {
            if (file.isDirectory()) {
                fileList.add(file.getName());
            }
        }
        Collections.sort(fileList, new Comparator<String>(){
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        });
        
        return fileList;
    }
    
    private int getLastFileIndex(List<String> list) {
        if (list != null && !list.isEmpty()) {
            String name  = list.get(list.size() - 1);
            String indexStr = name.substring(3);

            return Integer.valueOf(indexStr);
        } else {
            return 0;
        }
    }
    
    /** 获取当前正在使用的目录 */
    public String getCurrectDirName() {
        lock.lock();
        try{
            String dirName = getDirName(dirIndex.get());
            if (isDirFull(dirName)) {
                int index = dirIndex.addAndGet(1);
                return addDir(index);
            } else {
                return dirName;
            }
        }catch(Exception ex){
             ex.printStackTrace();
        }finally{
            lock.unlock();   //释放锁
        }
        return null;
    }
    
    /** 文件目录已满 */
    public boolean isDirFull(String dirName) {
        File dir = new File(getDirPath(dirName));
        if (dir.exists() && dir.isDirectory()) {
            int size = dir.list().length;
            if (size >= DIR_FILE_LIMIT) {
                return true;
            }
        } else if (!dir.exists()) {
            addDir(dirName);
            return false;
        }
        return false;
    }
    
    /**
     * @param index form 0 to 999999
     * @return
     */
    private String getDirName(int index) {
        String prefix = DIR_PREFIX;
        return String.format("%s%06d", prefix, index);
    }
    
    private String getDirPath(String dirName) {
        return DIR_ROOTDIR + dirName;
    }
    
    private String addDir(int index) {
        String dirName = getDirName(index);
        return addDir(dirName);
    }

    private String addDir(String dirName) {
        File dir = new File(getDirPath(dirName));
        if(!dir.exists()){
            dir.mkdir();
        }
        if (!sortedFileList.contains(dirName)) {
            sortedFileList.add(dirName);
        }
        return dirName;
    }
    
    /**
     * 
     * @param index
     * @return
     */
    private boolean createDir(int index) {
        String dirName = getDirName(index);
        File dir = new File(DIR_ROOTDIR + dirName);
        if(!dir.exists()){
            return dir.mkdir();
        }
        return true;
    }
    
    /**
     * 移除多余的文件
     * @param limit 保留的文件夹数目
     * @return
     */
    public void removeOldestDir(int limit) {
        if (sortedFileList != null && !sortedFileList.isEmpty()) {
            while (sortedFileList.size() > limit) {
                removeOldestDir(sortedFileList);
            }
        }
    }
    
    /** 如果文件夹存在, 删除 */
    private void removeOldestDir(List<String> list) {
        String fileName = list.remove(0);
        delDir(getDirPath(fileName));
    }
    
    private void delDir(String path) {
        File dir=new File(path);
        if(dir.exists()){
            logger.info("remove folder {} ", dir);
            File[] tmp = dir.listFiles();
            for(int i = 0; i < tmp.length; i++){
                if(tmp[i].isDirectory()){
                    delDir(path + "/" + tmp[i].getName());
                }else{
                    tmp[i].delete();
                }
            }
            dir.delete();
        }
    }
    
    public String getCurFilePath() {
        String dirName = getCurrectDirName();
        return getDirPath(dirName) + "/" + System.currentTimeMillis();
    }
    
    public static void main(String[] args){
        LocalFsMgr fsMgr = LocalFsMgr.getInstance();
        String curDirName = fsMgr.getCurrectDirName();
        logger.info("curDir = {} ", curDirName);
        fsMgr.removeOldestDir(1);
    }
}
